BARYCENTRIC_INTERP
Overview
The BARYCENTRIC_INTERP function performs polynomial interpolation using the barycentric formulation of Lagrange interpolation. Given a set of data points, it constructs a polynomial that passes exactly through all points, then evaluates that polynomial at specified locations. This technique is widely used in numerical analysis for curve fitting, data approximation, and function reconstruction.
Barycentric interpolation is a reformulation of Lagrange polynomial interpolation that offers improved numerical stability and computational efficiency. The method expresses the interpolating polynomial using pre-computed barycentric weights w_j, defined as:
w_j = \frac{1}{\prod_{m \neq j}(x_j - x_m)}
The interpolated value at any point x is then computed using the second (true) barycentric form:
L(x) = \frac{\sum_{j=0}^{k} \frac{w_j}{x - x_j} y_j}{\sum_{j=0}^{k} \frac{w_j}{x - x_j}}
This formulation avoids explicit computation of the polynomial coefficients, which enhances numerical stability. The algorithm is numerically stable because potential cancellation errors in the terms (x - x_j) appear in both numerator and denominator, effectively canceling out.
This implementation uses SciPy’s barycentric_interpolate function from the scipy.interpolate module. The source code is available in the SciPy GitHub repository.
Important consideration: While barycentric interpolation is numerically stable, polynomial interpolation itself can be ill-conditioned for certain node distributions due to Runge’s phenomenon, which causes large oscillations at the edges of the interval. For best results with many interpolation points, consider using Chebyshev nodes (points at \cos(i\pi/n)) rather than equally spaced points.
This example function is provided as-is without any representation of accuracy.
Excel Usage
=BARYCENTRIC_INTERP(xi, yi, x)
xi(list[list], required): The x-coordinates of the data pointsyi(list[list], required): The y-coordinates of the data pointsx(list[list], required): The x-coordinates at which to evaluate
Returns (list[list]): A 2D list (column vector) of interpolated values, or an error message (str) if invalid.
Examples
Example 1: Demo case 1
Inputs:
| xi | yi | x |
|---|---|---|
| 0 | 0 | 0.5 |
| 1 | 1 |
Excel formula:
=BARYCENTRIC_INTERP({0;1}, {0;1}, {0.5})
Expected output:
| Result |
|---|
| 0.5 |
Example 2: Demo case 2
Inputs:
| xi | yi | x |
|---|---|---|
| 0 | 0 | 1.5 |
| 1 | 1 | |
| 2 | 4 |
Excel formula:
=BARYCENTRIC_INTERP({0;1;2}, {0;1;4}, {1.5})
Expected output:
| Result |
|---|
| 2.25 |
Example 3: Demo case 3
Inputs:
| xi | yi | x |
|---|---|---|
| 1 | 1 | 1.5 |
| 2 | 4 | 2.5 |
| 3 | 9 |
Excel formula:
=BARYCENTRIC_INTERP({1;2;3}, {1;4;9}, {1.5;2.5})
Expected output:
| Result |
|---|
| 2.25 |
| 6.25 |
Example 4: Demo case 4
Inputs:
| xi | yi | x |
|---|---|---|
| 0 | 1 | 1 |
| 1 | 2 | |
| 2 | 5 | |
| 3 | 10 |
Excel formula:
=BARYCENTRIC_INTERP({0;1;2;3}, {1;2;5;10}, {1})
Expected output:
| Result |
|---|
| 2 |
Python Code
import math
from scipy.interpolate import barycentric_interpolate as scipy_barycentric_interpolate
def barycentric_interp(xi, yi, x):
"""
Interpolating polynomial for a set of points using barycentric interpolation.
See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.barycentric_interpolate.html
This example function is provided as-is without any representation of accuracy.
Args:
xi (list[list]): The x-coordinates of the data points
yi (list[list]): The y-coordinates of the data points
x (list[list]): The x-coordinates at which to evaluate
Returns:
list[list]: A 2D list (column vector) of interpolated values, or an error message (str) if invalid.
"""
def to2d(val):
"""Convert scalar or 2D list to 2D list format."""
return [[val]] if not isinstance(val, list) else val
def flatten(arr):
"""Flatten a 2D list to a 1D list."""
return [item for sublist in arr for item in sublist]
def validate_numeric_list(arr, name):
"""Validate that a 2D list contains only finite numeric values."""
if not isinstance(arr, list):
return f"Invalid input: {name} must be a list."
if not arr:
return f"Invalid input: {name} cannot be empty."
for i, row in enumerate(arr):
if not isinstance(row, list):
return f"Invalid input: {name} must be a 2D list."
for j, val in enumerate(row):
if not isinstance(val, (int, float)):
return f"Invalid input: {name}[{i}][{j}] must be numeric."
if math.isnan(val) or math.isinf(val):
return f"Invalid input: {name}[{i}][{j}] must be finite."
return None
# Normalize inputs to 2D lists
xi = to2d(xi)
yi = to2d(yi)
x = to2d(x)
# Validate inputs
error = validate_numeric_list(xi, "xi")
if error:
return error
error = validate_numeric_list(yi, "yi")
if error:
return error
error = validate_numeric_list(x, "x")
if error:
return error
# Flatten to 1D arrays
xi_flat = flatten(xi)
yi_flat = flatten(yi)
x_flat = flatten(x)
# Check that xi and yi have the same length
if len(xi_flat) != len(yi_flat):
return "Invalid input: xi and yi must have the same length."
# Check minimum points requirement
if len(xi_flat) < 1:
return "Invalid input: at least one data point is required."
# Check for duplicate xi values
if len(xi_flat) != len(set(xi_flat)):
return "Invalid input: xi values must be unique."
try:
# Call scipy.interpolate.barycentric_interpolate
result = scipy_barycentric_interpolate(xi_flat, yi_flat, x_flat)
# Convert result to list and validate
if hasattr(result, '__iter__'):
result_list = list(result)
else:
result_list = [result]
# Validate all results are finite
for i, val in enumerate(result_list):
if not isinstance(val, (int, float)):
return f"scipy.interpolate.barycentric_interpolate error: non-numeric result at index {i}."
if math.isnan(val) or math.isinf(val):
return f"scipy.interpolate.barycentric_interpolate error: non-finite result at index {i}."
# Return as 2D column vector
return [[float(val)] for val in result_list]
except Exception as exc:
return f"scipy.interpolate.barycentric_interpolate error: {exc}"